
<style lang="less">
    .zk-multi-tabs{
        height: 64px;
        overflow: hidden;
        background-color: #fff;
        position: relative;
        margin-top: -24px;
        padding-top: 10px;
        margin-bottom: 10px;
        .reload{
            margin-left: 10px;
        }
    }
</style>
<template>
    <div>
        <div class="zk-multi-tabs">
            <a-tabs v-model="activeKey" type="editable-card" :tabBarStyle="{background: '#FFF', margin: 0, paddingLeft: '18px', paddingTop: '1px'}" :tabBarGutter="3" :hideAdd="true" @edit="onEdit">
                <a-tab-pane v-for="(page, index) in pages" :key="page.fullPath" style="height: 0;" :closable="index>0">
                    <template #tab>
                        <span>{{titleDic[page.fullPath]||page.meta.title}}</span>
                        <a-icon v-show="activeKey==page.fullPath" class="reload" type="reload" :spin="loading" @click="refresh()"/>
                    </template>
                </a-tab-pane>
            </a-tabs>
        </div>
    </div>
</template>
<script>
import Vue from 'vue';
import config from '@/config/index';
export default {
    name:"ZkMultiTabs",
    data() {
        return {
            activeKey:'',
            pages:[],
            fullPathList:[],
            loading:false,
            titleDic:{}
        }
    },
     watch: {
        '$route': function(newVal){
            this.activeKey = newVal.fullPath;
            if (this.fullPathList.indexOf(newVal.fullPath) < 0) {
                this.fullPathList.push(newVal.fullPath);
                this.pages.push(newVal);
                return;
            }
            if (newVal.fullPath == config.homeIndex ) {
                this.pages[0] = newVal;
                this.fullPathList[0] = newVal.fullPath;
            }
        },
        activeKey: function (newPathKey) {
            this.$router.push({ path: newPathKey })
        }
    },
    created() {
        if (this.$route.path.indexOf(config.homeIndex)<=-1) {
            // 非首页初始化
            this.pages.push({
                path: config.homeIndex,
                fullPath:config.homeIndex,
                meta:{ title:'首页' }
            });
            this.fullPathList.push(config.homeIndex);
        }
        this.pages.push(this.$route);
        this.fullPathList.push(this.$route.fullPath);
        this.selectedLastPath();
        // 挂载到全局上供调用
        Vue.prototype.$zkMultiTabs = {
            close:(fullPath)=>{
                if (!fullPath) {
                    // 未传入则默认关闭当前
                    fullPath = this.activeKey;
                }
                this.remove(fullPath);
            },
            refresh:(fullPath)=>{
                this.refresh(fullPath);
            },
            setTitle:(title)=>{
                // 设置自定义 title
                this.titleDic[this.$route.fullPath] = title;
                this.$forceUpdate();
            }
        }
    },
    methods: {
        /**
         * 刷新页面
         */
        refresh(fullPath){
            if (fullPath&&fullPath!=this.activeKey) {
                // 非当前页面仅清空缓存
                this.clearKeepAliveByFullPath(fullPath);
                return;
            }
            this.loading = true;
            // 未传入或者当前页面则常规刷新
            this.clearKeepAliveByFullPath(this.activeKey);
            setTimeout(() => {
                this.loading = false;
            }, 1000);
            
            this.$store.commit('UpdateRouterViewState', false);
            this.$nextTick(()=>{
                this.$store.commit('UpdateRouterViewState', true);
            });
        },
        onEdit(targetKey, action) {
            this[action](targetKey);
        },
        remove(targetKey) {
            this.clearKeepAliveByFullPath(targetKey);
            if (this.pages.length==1) {
                // 只有一个则阻止关闭
                return;
            }
            this.pages = this.pages.filter(page => page.fullPath !== targetKey)
            this.fullPathList = this.fullPathList.filter(path => path !== targetKey)
            // 判断当前标签是否关闭，若关闭则跳转到最后一个还存在的标签页
            if (!this.fullPathList.includes(this.activeKey)) {
                this.selectedLastPath();
            }
        },
        selectedLastPath() {
            this.activeKey = this.fullPathList[this.fullPathList.length - 1]
        },
        clearKeepAlive(that){
            let vnode = that.$vnode
            let parentVnode = vnode.parent 
            if (parentVnode && parentVnode.componentInstance.cache) {
                var key = vnode.key == null
                ? vnode.componentOptions.Ctor.cid + (vnode.componentOptions.tag ? `::${vnode.componentOptions.tag}` : '')
                : vnode.key;
                var cache = parentVnode.componentInstance.cache;
                var keys  = parentVnode.componentInstance.keys;

                if (cache[key]) {
                that.$destroy()
                // remove key
                if (keys.length) {
                    var index = keys.indexOf(key)
                    if (index > -1) {
                        keys.splice(index, 1)
                    }
                }
                cache[key] = null
                }
            }
        },
        clearKeepAliveByFullPath(targetKey){
            const items = this.pages.filter(page=>page.fullPath == targetKey||page.path==targetKey);
            items.forEach(item=>{
                const ins = item.matched[item.matched.length-1].instances.default;
                if(ins){
                    this.clearKeepAlive(ins);
                    console.log('清除缓存成功！',item);
                }
            });
            if(items.length==0)console.info('该页面未在页签中打开！',targetKey);
        }
    }
}
</script>